package com.okhttp.retrofit;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.okhttp.utils.Utils;
import com.okhttp.utils.RetrofitLog;
import java.io.Reader;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;

/**
 * @author GYL
 * @dateTime 2020/4/22-14:02
 * @description 统一返回ResponseBody,需要手动解body数据
 */
public abstract class BaseResponseBodyHandler<T> implements CallbackStub<T,ResponseBody> {
  
  private static final String TAG = "ResponseBodyHandler";
  private int mWhat;
  private final ReferenceQueue<IHandlerContext> mRfq=new ReferenceQueue<>();
  private IHandlerContext mHContext;
  
  public BaseResponseBodyHandler(){
    this(null);
  }
  
  public BaseResponseBodyHandler(IHandlerContext context){
    if(context!=null) {
      final WeakReference<? extends IHandlerContext> mWrfContext = new WeakReference<>(context, mRfq);
      mHContext = mWrfContext.get();
    }
  }
  
  private Type getGenericityType(){
    Type type = getClass().getGenericSuperclass();
    if(type instanceof ParameterizedType){
      return ((ParameterizedType) type).getActualTypeArguments()[0];
    }
    return type;
  }
  
  protected String getString(int strId,String def){
//    if(mHContext!=null && mHContext.getCurrentContext()!=null){
//      return mHContext.getCurrentContext().getString(strId);
//    }
    return def;
  }
  
  protected void showProgress(int what){
    if(mHContext!=null){
      mHContext.showProgress("");
    }
  }
  
  protected void dismissProgress(int what){
    if(mHContext!=null){
      mHContext.dismissProgress();
    }
  }
  
  @Override
  public void onBeforeExecute(int what) {
    this.mWhat=what;
    this.showProgress(mWhat);
  }
  
  @Override
   public T convertBody(ResponseBody responseBody){
    if(responseBody==null){
      RetrofitLog.e(TAG, "response body is null");
      return null;
    }
    Reader reader = null;
    try{
      reader=responseBody.charStream();
      Gson gson = new Gson();
      Type type = new TypeToken<T>() {}.getType();
      T t = gson.fromJson(reader, getGenericityType());
      return t;
    }catch (Exception e){
      RetrofitLog.e(TAG, e.getMessage(), e);
      return null;
    }finally {
      Utils.close(reader,responseBody);
    }
  }
  
  @Override
  public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
    try {
      RetrofitLog.d(TAG, "response code:" + response.code() + " message:" + response.message());
      dismissProgress(mWhat);
      if (response.isSuccessful()) {
        T t = convertBody(response.body());
        if (t == null) {
          RetrofitLog.e(TAG, "result:null");
          if (DISK_CACHE_DATA.equals(response.message())
                || NET_DATA.equals(response.message())) {
            onHandler(mWhat, String.valueOf(ERROR_NO_DATA), "暂无数据", null);
          } else {
            onHandler(mWhat, ERROR_CODE, "暂无数据", null);
          }
        } else {
          onHandler(mWhat, String.valueOf(response.code()), "请求成功", t);
        }
      } else {
        if(ERROR_NET_INVALID==response.code()){
          onHandler(mWhat, String.valueOf(response.code()), "网络未联接,请检查网络", null);
        }else if(ERROR_NET_TIMEOUT==response.code()){
          onHandler(mWhat, String.valueOf(response.code()), "请求超时", null);
        }else{
          onHandler(mWhat, String.valueOf(response.code()), "请求失败", null);
        }
      }
    } catch (Exception e) {
      RetrofitLog.e(TAG, e.getMessage(), e);
      onHandler(mWhat, ERROR_CODE,"请求失败", null);
    } finally {
      call.cancel();
    }
  }
  
  @Override
  public void onFailure(Call<ResponseBody> call, Throwable t) {
    dismissProgress(mWhat);
    // 请求失败统一处理
    RetrofitLog.e(TAG, t.getMessage(), t);
    onHandler(mWhat,ERROR_CODE, "请求失败",null);
    call.cancel();
  }
}
